﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using Work.BL.Managers;
using Work.BL.POCOs;
using Work.DAL.Hibernate.Abstract;
using Work.DAL.Hibernate.Entities;
using Work.Tools.ObjectMapper;

namespace Work.BL.Hibernate.Managers
{
    public class HVacancyManager : IVacancyManager
    {
        #region Fields

        private readonly ICWSessionFactory _sessionFactory;
        private readonly IObjectMapper _objectMapper;

        #endregion

        #region Constructors

        public HVacancyManager(ICWSessionFactory sessionFactory, IObjectMapper objectMapper)
        {
            this._sessionFactory = sessionFactory;
            this._objectMapper = objectMapper;
        }

        #endregion

        #region IProjectManager Members

        public List<VacancyPOCO> GetVacancies()
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                IList<Vacancy> users = session.CreateCriteria<Vacancy>().List<Vacancy>();
                return users
                    .Select(r => this._objectMapper.Map<Vacancy, VacancyPOCO>(r))
                    .ToList();
            }
        }

        public List<VacancyPOCO> GetVacancies(int startIndex, int maxCount)
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                IList<Vacancy> sections = session.CreateCriteria<Vacancy>()
                    .SetFirstResult(startIndex)
                    .SetMaxResults(maxCount)
                    .List<Vacancy>();
                List<VacancyPOCO> list = sections
                    .Select(r => this._objectMapper.Map<Vacancy, VacancyPOCO>(r))
                    .ToList();
                return list;
            }
        }

        public int GetVacancyCount()
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                int rowCount = session.CreateCriteria<Vacancy>()
                    .SetProjection(Projections.RowCount()).UniqueResult<int>();
                return rowCount;
            }
        }

        public VacancyPOCO Insert(VacancyPOCO vacancyPoco)
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                Vacancy vacancy = _objectMapper.Map<VacancyPOCO, Vacancy>(vacancyPoco);
                session.Save(vacancy);
                session.Flush();
                return _objectMapper.Map<Vacancy, VacancyPOCO>(vacancy);
            }
        }

        public VacancyPOCO GetVacancyById(int id)
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                Vacancy vacancy = session.Get<Vacancy>(id);
                return _objectMapper.Map<Vacancy, VacancyPOCO>(vacancy);
            }
        }

        public VacancyPOCO Block(VacancyPOCO vacancyPoco)
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                Vacancy vacancy = _objectMapper.Map<VacancyPOCO, Vacancy>(vacancyPoco);
                if (vacancy.IsBlocked)
                {
                    vacancy.IsBlocked = false;
                }
                else
                {
                    vacancy.IsBlocked = true;
                }
                session.Save(vacancy);
                session.Flush();
                return _objectMapper.Map<Vacancy, VacancyPOCO>(vacancy);
            }
        }

        public object Delete(VacancyPOCO vacancyPoco)
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                Vacancy vacancy = _objectMapper.Map<VacancyPOCO, Vacancy>(vacancyPoco);
                session.Delete(vacancy);
                session.Flush();
                return _objectMapper.Map<Vacancy, VacancyPOCO>(vacancy);
            }
        }

        public List<VacancyPOCO> Search(string text)
        {
            using (ISession session = this._sessionFactory.CreateSession())
            {
                var criteria = session.CreateCriteria<Vacancy>();
                if (!string.IsNullOrWhiteSpace(text))
                {
                    criteria = criteria.Add(Restrictions.Like("Title", text, MatchMode.Anywhere));
                }
                IList<Vacancy> list = criteria.List<Vacancy>();
                return list.Select(v => this._objectMapper.Map<Vacancy, VacancyPOCO>(v)).ToList();
            }
        }

        #endregion

    }
}
